//01/09/2009
package lwf.factory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.TreeMap;


public class SynonymFactory {
	
	private static SynonymFactory instance = null;
	
	private ResourceBundle synonymsBundle = null;
	
	private Map mapSynonyms = null;
	private List synonymalphabet = null;
	
	
	private SynonymFactory() {
		init();
	}

	
	public synchronized final static SynonymFactory getInstance(){
		if (instance == null) {
			instance = new SynonymFactory();
		}
		return instance;
	}
	
	//---------------------------------------------------------------------------------------------
	// Customized methods
	//---------------------------------------------------------------------------------------------
	public Map getSynonyms() {
		if(mapSynonyms == null) {
			this.processSynonyms(synonymsBundle);
		}
		return mapSynonyms;
	}
	
	public List getSynonymAlphabets() {
		if(synonymalphabet == null) {
			this.processSynonyms(synonymsBundle);
			Collections.sort(synonymalphabet);
		}
		return synonymalphabet;
	}

	//---------------------------------------------------------------------------------------------
	// Private methods
	//---------------------------------------------------------------------------------------------
	
	private void init() {
		if(synonymsBundle == null) {
			synonymsBundle = ResourceBundle.getBundle("general.synonyms");
		}
	}

	/**
	 * Processes the synonyms data and creates a Map object. The key in the map object is
	 * the alphabet and the value is again a map object in which the key is the word and
	 * value is (a String array) synonyms.
	 * 
	 * This also populates a collection in which all the available synonym starting alphabets are
	 * stored.
	 * 
	 * @param resource
	 */
	private void processSynonyms(ResourceBundle resource) {

		if(synonymalphabet == null) {
			synonymalphabet = new ArrayList();
		}
		if(mapSynonyms == null) {
			mapSynonyms = new TreeMap();
		}
		Enumeration enum1 = resource.getKeys();
		while(enum1.hasMoreElements()) {
			String key = enum1.nextElement().toString();
			String value = resource.getString(key);
			StringTokenizer stk = new StringTokenizer(value, ",");
			int tokens = stk.countTokens();
			String[] values = new String[tokens];
			int counter = 0;
			while(stk.hasMoreTokens()) {
				values[counter] = stk.nextToken();
				counter++;
			}
			for(int i=0; i<tokens; i++) {
				String[] synonymval = new String[tokens-1];
				String synonymkey = values[i];
				int valCounter = 0;
				for(int j=0; j<values.length; j++) {
					if(i != j) {
						synonymval[valCounter] = values[j];
						valCounter++;
					}
				}
				Arrays.sort(synonymval);
				String startalphabet = synonymkey.substring(0,1);
				Map mapalphasynonym = null;
				if(mapSynonyms.containsKey(startalphabet)) {
					mapalphasynonym = (Map)mapSynonyms.get(startalphabet);
				}
				else {
					if(startalphabet.trim().length() != 0) {
						synonymalphabet.add(startalphabet.trim());	
					}
					
					mapalphasynonym = new TreeMap();
				}

				mapalphasynonym.put(synonymkey, synonymval);
				mapSynonyms.put(startalphabet, mapalphasynonym);
			}
		}
	}
	
}
